package com.spider.gp.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.spider.gp.dao.*;
import com.spider.gp.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * description:
 *
 * @author clare
 * @date 2022/06/14 17:05
 **/
@Controller
@Slf4j
public class TongJiController {
    @Autowired
    private LianBanDao lianBanDao;
    @Autowired
    private ShouBanDao shouBanDao;
    @Autowired
    private GpTjDao gpTjDao;
    @Autowired
    private ZhiShuDao zhiShuDao;
    @Autowired
    private DieTingDao dieTingDao;
    @Autowired
    private LowHighDao lowHighDao;
    @Autowired
    private LowHighTjDao lowHighTjDao;
    @Autowired
    private GpDetailDao gpDetailDao;

    @Autowired
    private LowHighTjDetailDao lowHighTjDetailDao;

    @Autowired
    private LowHighTjSsypDao lowHighTjSsypDao;

    public void lowTjDetail() {
        LambdaQueryWrapper<LowHighTjDetail> wrapperDetail = new LambdaQueryWrapper<>();
        wrapperDetail.orderByDesc(LowHighTjDetail::getReportTime).last(" limit 1 ");
        LowHighTjDetail lowHighTjDetail = lowHighTjDetailDao.selectOne(wrapperDetail);


        LambdaQueryWrapper<LowHighTj> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(wra -> wra.like(LowHighTj::getLowGpsCode, "1000001").or().like(LowHighTj::getLowGpsCode, "0399001").or()
                .like(LowHighTj::getHighGpsCode, "1000001").or().like(LowHighTj::getHighGpsCode, "0399001"));
        if (lowHighTjDetail != null) {
            wrapper.gt(LowHighTj::getReportTime, lowHighTjDetail.getReportTime());
        }

        wrapper.orderByDesc(LowHighTj::getReportTime);
        List<LowHighTj> lowHighTjs = lowHighTjDao.selectList(wrapper);

        if (lowHighTjs == null || lowHighTjs.size() == 0) {
            return;
        }
//        String reportTime = lowHighTjs.get(0).getReportTime();

        lowHighTjs.parallelStream().forEach(e -> {
            List<String> gps = new ArrayList<>();
            List<String> gpsZz = new ArrayList<>();


            if (e.getLowState().contains("1")) {
                String[] gpsl = e.getLowGpsCode().split(";");
                for (String m : gpsl) {
                    gps.add(m);
                }
            }


            if (e.getHighState().contains("1")) {
                String[] gpsh = e.getHighGpsCode().split(";");
                for (String m : gpsh) {
                    gps.add(m);
                }
            }

            if (gps.size() == 0) {
                return;
            }


//            LambdaQueryWrapper<LowHigh> wrapperLH = new LambdaQueryWrapper<>();
//            wrapperLH.and(wra -> wra.eq(LowHigh::getState, "02").or().eq(LowHigh::getState, "22"));
//            wrapperLH.in(LowHigh::getCode ,gps );
//            List<LowHigh> one = lowHighDao.selectList(wrapperLH);
//
//            one.forEach(m -> {
//                gpsZz.add(m.getCode());
//            });

            gps.forEach(a -> {
                LambdaQueryWrapper<GpDetail> w = new LambdaQueryWrapper<>();
                w.eq(GpDetail::getCode, a);
                GpDetail gpDetail = gpDetailDao.selectOne(w);

                if (gpDetail == null) {
                    return;
                }
                String detail = gpDetail.getDetail();

                if (Strings.isNotBlank(detail)) {

                    String[] split = detail.split(";");


                    for (int i = 0; i < split.length; i++) {

                        String time = split[i].split(",")[0];

                        if (!time.equals(e.getReportTime())) {
                            continue;
                        }


                        insertDetailDetail(e, a, gpDetail, split, i, time);

                    }

                }

            });
        });
    }

    // 实时
    public void lowTjDetailSS() {

        LambdaQueryWrapper<LowHighTj> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(wra -> wra.like(LowHighTj::getLowGpsCode, "1000001").or().like(LowHighTj::getLowGpsCode, "0399001").or()
                .like(LowHighTj::getHighGpsCode, "1000001").or().like(LowHighTj::getHighGpsCode, "0399001"));
        wrapper.and(wra -> wra.like(LowHighTj::getLowState, "1").or().like(LowHighTj::getHighState, "1"));
        wrapper.orderByDesc(LowHighTj::getReportTime);
        wrapper.last(" limit 3 ");
        List<LowHighTj> lowHighTjs = lowHighTjDao.selectList(wrapper);

        if (lowHighTjs == null || lowHighTjs.size() == 0) {
            return;
        }

        //删除全表
        int delete = lowHighTjSsypDao.delete(new LambdaQueryWrapper<>());
//        String reportTime = lowHighTjs.get(0).getReportTime();

        lowHighTjs.parallelStream().forEach(e -> {
            List<String> gps = new ArrayList<>();
            List<String> gpsZz = new ArrayList<>();


            if (e.getLowState().contains("1")) {
                String[] gpsl = e.getLowGpsCode().split(";");
                for (String m : gpsl) {
                    gps.add(m);
                }
            }


            if (e.getHighState().contains("1")) {
                String[] gpsh = e.getHighGpsCode().split(";");
                for (String m : gpsh) {
                    gps.add(m);
                }
            }

            if (gps.size() == 0) {
                return;
            }


            gps.forEach(a -> {
                LambdaQueryWrapper<GpDetail> w = new LambdaQueryWrapper<>();
                w.eq(GpDetail::getCode, a);
                GpDetail gpDetail = gpDetailDao.selectOne(w);

                if (gpDetail == null) {
                    return;
                }
                String detail = gpDetail.getDetail();

                if (Strings.isNotBlank(detail)) {

                    String[] split = detail.split(";");


                    for (int i = 0; i < split.length; i++) {

                        String time = split[i].split(",")[0];

                        if (!time.equals(e.getReportTime())) {
                            continue;
                        }
                        //实时
                        if ( (i +10) <= split.length - 1 && (split.length ) <= (i +20)){

                            String p10 = split[i +10];//第i+j 天
                            String td = split[split.length -1 ].split(",")[1];//今日价格
                            String s10 = p10.split(",")[1];
                            BigDecimal ten = new BigDecimal(s10);//第10天
                            BigDecimal zdz = new BigDecimal(s10);//最大值
                            BigDecimal zxz = new BigDecimal(s10);//最小值
                            BigDecimal tdj = new BigDecimal(td);//最小值
                            int zdzTs = 10;//最大值天数
                            int zxzTs = 10;//最小值天数
                            for (int j = i +10; j < split.length; j++) { //包括第10天
                                String pij = split[j];//第10天
                                String spj = pij.split(",")[1];
                                BigDecimal spjd = new BigDecimal(spj);

                                //flag = -1,表示bigdemical1小于bigdemical2；
                                //flag = 0,表示bigdemical1等于bigdemical2；
                                //flag = 1,表示bigdemical1大于bigdemical2；
                                if (spjd.compareTo(zxz) <= 0) {
                                    //最小值
                                    zxz = spjd;
                                    zxzTs = j - i;
                                }

                                if (spjd.compareTo(zdz) >= 0) {
                                    //最大值
                                    zdz = spjd;
                                    zdzTs = j - i;
                                }
                            }
                            // 最大涨幅
                            BigDecimal zf = zdz.subtract(ten).multiply(new BigDecimal(100)).divide(ten, 2, BigDecimal.ROUND_HALF_UP);
                            // 最大跌幅
                            BigDecimal df = zxz.subtract(ten).multiply(new BigDecimal(100)).divide(ten, 2, BigDecimal.ROUND_HALF_UP);
                            //当前涨幅
                            BigDecimal dq = tdj.subtract(ten).multiply(new BigDecimal(100)).divide(ten, 2, BigDecimal.ROUND_HALF_UP);

                            String state = "1";
                            //判断入库 1. 最大跌幅大于5% 不入库  最小值天数大于12不入库
                            if (df.add(new BigDecimal(5)).compareTo(new BigDecimal(0)) <= 0){
                                //如果跌幅+5个点还是
                                state = "0";
                            }
                            if (zxzTs > 12){
                                //最小值天数大于12不入库
                                state = "0";
                            }

                            if (zf.compareTo(new BigDecimal(5)) <= 0){
                                //当前最高值小于5个点的排除
                                state = "0";
                            }

                            if (dq.compareTo(new BigDecimal(5)) <= 0){
                                //当前涨幅小于5个点的排除
                                state = "0";
                            }



                            lowHighTjSsypDao.insert(LowHighTjSsyp.builder().reportTime(time).code(a).name(gpDetail.getName())
                                    .lowState(e.getLowState()).highState(e.getHighState())
                                    .tenPrice(String.valueOf(ten)).todayPrice(String.valueOf(td))
                                    .zfQj(String.valueOf(zf)).dfQj(String.valueOf(df))
                                    .zdjgQj(String.valueOf(zdz)).zxjgQj(String.valueOf(zxz)).zgjTs(String.valueOf(zdzTs)).zdjTs(String.valueOf(zxzTs))
                                    .state(state).dqZf(String.valueOf(dq)).build());

                        }

                    }

                }

            });
        });
    }





    private void insertDetailDetail(LowHighTj e, String a, GpDetail gpDetail, String[] split, int i, String time) {
        if ((i + 20) <= split.length -1 ) {
            //找到了
            String p10 = split[i +10];//第i+j 天
            String s10 = p10.split(",")[1];
            BigDecimal ten = new BigDecimal(s10);//第10天
            BigDecimal tenOne = new BigDecimal(s10);//第11天
            BigDecimal twoTen = new BigDecimal(s10);//第20天
            BigDecimal zdz = new BigDecimal(0);//最大值
            BigDecimal zxz = new BigDecimal(s10);//最小值
            int zdzTs = 10;//最大值天数
            int zxzTs = 10;//最小值天数
            for (int j = 11; j < 21; j++) {
                String pij = split[i + j];//第i+j 天
                String spj = pij.split(",")[1];
                BigDecimal spjd = new BigDecimal(spj);
                if (j == 11) {
                    tenOne = spjd;
                }
                if (j == 20) {
                    twoTen = spjd;
                }
                //flag = -1,表示bigdemical1小于bigdemical2；
                //flag = 0,表示bigdemical1等于bigdemical2；
                //flag = 1,表示bigdemical1大于bigdemical2；
                if (spjd.compareTo(zxz) <= 0) {
                    //最小值
                    zxz = spjd;
                    zxzTs = j;
                }

                if (spjd.compareTo(zdz) > 0) {
                    //最大值
                    zdz = spjd;
                    zdzTs = j;
                }

            }
            // 最大涨幅
            BigDecimal zf = zdz.subtract(ten).multiply(new BigDecimal(100)).divide(ten, 2, BigDecimal.ROUND_HALF_UP);
            // 最大跌幅
            BigDecimal df = zxz.subtract(ten).multiply(new BigDecimal(100)).divide(ten, 2, BigDecimal.ROUND_HALF_UP);


            lowHighTjDetailDao.insert(LowHighTjDetail.builder().reportTime(time).code(a).name(gpDetail.getName())
                    .lowState(e.getLowState()).highState(e.getHighState())
                    .tenPrice(String.valueOf(ten)).tenOnePrice(String.valueOf(tenOne)).twoTenPrice(String.valueOf(twoTen))
                    .zfQj(String.valueOf(zf)).dfQj(String.valueOf(df))
                    .zdjgQj(String.valueOf(zdz)).zxjgQj(String.valueOf(zxz)).zgjTs(String.valueOf(zdzTs)).zdjTs(String.valueOf(zxzTs)).build());

        }
    }

    public void lhtjAll( List<ZhiShu> zhiShus ) {

//        LambdaQueryWrapper<ZhiShu> wrapperZS = new LambdaQueryWrapper<>();
//        if (Strings.isNotBlank(reportTime)){
//            wrapperZS.eq(ZhiShu::getReportTime , reportTime);
//        }
////        wrapperZS.notInSql(ZhiShu::getReportTime, "select report_time from low_high_tj group by report_time ");
//        List<ZhiShu> zhiShus = zhiShuDao.selectList(wrapperZS);

        zhiShus.forEach(e -> {
            LambdaQueryWrapper<LowHighTj> wrapperTjQ = new LambdaQueryWrapper<>();
            wrapperTjQ.eq(LowHighTj::getReportTime, e.getReportTime());
            LowHighTj lowHighTj = lowHighTjDao.selectOne(wrapperTjQ);

            String replaceTime = e.getReportTime().replace("-", "");
            LambdaQueryWrapper<LowHigh> wrapperQ = new LambdaQueryWrapper<>();
            wrapperQ.like(LowHigh::getLowPoint, replaceTime);
            List<LowHigh> lowHighs = lowHighDao.selectList(wrapperQ);//该天最低点gp
            int sizel = lowHighs.size(); //数量
            StringBuffer lowStr = new StringBuffer();
            StringBuffer lowStrCode = new StringBuffer();
            StringBuffer lowState = new StringBuffer();
            lowHighs.forEach(a -> {
                lowStr.append(a.getName()).append(";");
                lowStrCode.append(a.getCode()).append(";");
            });

            LambdaQueryWrapper<LowHigh> wrapperQH = new LambdaQueryWrapper<>();
            wrapperQH.like(LowHigh::getHighPoint, replaceTime);
            List<LowHigh> lowHighsH = lowHighDao.selectList(wrapperQH);//该天最高点gp
            int sizeh = lowHighsH.size(); //数量
            StringBuffer highStr = new StringBuffer();
            StringBuffer highStrCode = new StringBuffer();
            StringBuffer highState = new StringBuffer();

            lowHighsH.forEach(a -> {
                highStr.append(a.getName()).append(";");
                highStrCode.append(a.getCode()).append(";");

            });

            if (lowStr.toString().contains("上证")) {
                lowState.append("1");
            } else {
                lowState.append("0");
            }

            if (lowStr.toString().contains("深证")) {
                lowState.append("1");
            } else {
                lowState.append("0");
            }

            if (highStr.toString().contains("上证")) {
                highState.append("1");
            } else {
                highState.append("0");
            }

            if (highStr.toString().contains("深证")) {
                highState.append("1");
            } else {
                highState.append("0");
            }

            if (lowHighTj != null) {
                lowHighTjDao.updateById(LowHighTj.builder().reportTime(e.getReportTime())
                        .lowCount(String.valueOf(sizel)).highCount(String.valueOf(sizeh))
                        .lowGps(lowStr.toString()).highGps(highStr.toString())
                        .lowState(lowState.toString()).highState(highState.toString())
                        .lowGpsCode(lowStrCode.toString()).highGpsCode(highStrCode.toString()).build());
            } else {
                lowHighTjDao.insert(LowHighTj.builder().reportTime(e.getReportTime())
                        .lowCount(String.valueOf(sizel)).highCount(String.valueOf(sizeh))
                        .lowGps(lowStr.toString()).highGps(highStr.toString())
                        .lowState(lowState.toString()).highState(highState.toString())
                        .lowGpsCode(lowStrCode.toString()).highGpsCode(highStrCode.toString()).build());
            }

        });

    }


    //涨跌停比
    public void zdtb(String reportTime) {


        LambdaQueryWrapper<GpTj> wrapperQ = new LambdaQueryWrapper<>();
        wrapperQ.eq(GpTj::getReportTime, reportTime);
        GpTj gpTj = gpTjDao.selectOne(wrapperQ);

        if (gpTj == null) {
            gpTjDao.insert(GpTj.builder().reportTime(reportTime).build());
        }


        LambdaQueryWrapper<DieTing> wrapper = new LambdaQueryWrapper();
        wrapper.eq(DieTing::getReportTime, reportTime);
        Integer dt = dieTingDao.selectCount(wrapper);

        LambdaQueryWrapper<LianBan> wrapper01 = new LambdaQueryWrapper();
        wrapper01.eq(LianBan::getReportTime, reportTime);
        Integer lb = lianBanDao.selectCount(wrapper01);


        LambdaQueryWrapper<ShouBan> wrapper02 = new LambdaQueryWrapper();
        wrapper02.eq(ShouBan::getReportTime, reportTime);
        Integer sb = shouBanDao.selectCount(wrapper02);

        StringBuffer buffer = new StringBuffer();
        if (gpTj.getZtbdt() != null) {
            buffer.append(gpTj.getZtbdt()).append(";");
        }
        buffer.append(lb + sb).append("/").append(dt);
        gpTjDao.updateById(GpTj.builder().reportTime(reportTime).ztbdt(buffer.toString()).build());
    }


    //成交量统计
    public void cJList(String reportTime) {

//        SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd");
//        String reportTime =formatter.format(new Date());
//        String reportTime ="2022-09-02";
        LambdaQueryWrapper<ZhiShu> wrapper = new LambdaQueryWrapper();
        wrapper.eq(ZhiShu::getReportTime, reportTime);
        ZhiShu zhiShu = zhiShuDao.selectOne(wrapper);
        String szzsCjl = zhiShu.getSzzsCjl();//上证指数成交量
        String szczCjl = zhiShu.getSzczCjl();//深圳指数成交量

        String valueSH = szzsCjl.split("亿")[0];
        String valueSC = szczCjl.split("亿")[0];

        BigDecimal total = new BigDecimal(valueSH).add(new BigDecimal(valueSC));


        LambdaQueryWrapper<GpTj> wrapperQ = new LambdaQueryWrapper<>();
        wrapperQ.eq(GpTj::getReportTime, reportTime);
        GpTj gpTj = gpTjDao.selectOne(wrapperQ);
        if (gpTj == null) {
            gpTjDao.insert(GpTj.builder().reportTime(reportTime).build());
        }

        StringBuffer valueStr = new StringBuffer();

        if (gpTj != null && gpTj.getCjl() != null) {
            valueStr.append(gpTj.getCjl()).append(";");
        }
        valueStr.append(total.toString()).append("亿");

        gpTjDao.updateById(GpTj.builder().reportTime(reportTime).cjl(valueStr.toString()).build());
    }


    //妖股统计
    public void yaogu(String reportTime) {
//        SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd");
//        String reportTime =formatter.format(new Date());
//        String reportTime ="2022-09-02";

        LambdaQueryWrapper<GpTj> wrapperQ = new LambdaQueryWrapper<>();
        wrapperQ.eq(GpTj::getReportTime, reportTime);
        GpTj gpTj = gpTjDao.selectOne(wrapperQ);

        if (gpTj == null) {
            gpTjDao.insert(GpTj.builder().reportTime(reportTime).build());
        }

//        String reportTimeY = formatter.format(new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24));
        LambdaQueryWrapper<LianBan> wrapperT = new LambdaQueryWrapper<>();
        wrapperT.lt(LianBan::getReportTime, reportTime); //小于今天的最大
        wrapperT.orderByDesc(LianBan::getReportTime);
        wrapperT.last("limit 1");
        LianBan lianBanY = lianBanDao.selectOne(wrapperT);

        String reportTimeY = lianBanY.getReportTime();
        List<String> datas = new ArrayList<>();

        LambdaQueryWrapper<LianBan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LianBan::getReportTime, reportTime); // 今天 4板的
        wrapper.ge(LianBan::getLbc, 4);//大于等于4板
        List<LianBan> lianBans = lianBanDao.selectList(wrapper);

        LambdaQueryWrapper<LianBan> wrapperY = new LambdaQueryWrapper<>();
        wrapperY.eq(LianBan::getReportTime, reportTimeY);
        wrapperY.ge(LianBan::getLbc, 3);//大于等于3板
        List<LianBan> lianBansY = lianBanDao.selectList(wrapperY);

        AtomicInteger i = new AtomicInteger();
        BigDecimal value = new BigDecimal(0);
        StringBuffer valueStr = new StringBuffer();
        if (lianBans != null && lianBansY != null) {
            lianBans.forEach(e -> {
                lianBansY.stream().filter(a -> a.getCode().equals(e.getCode())).forEach(a -> {
                    i.getAndIncrement();
                    datas.add(a.getCode() + a.getName() + "|" + e.getLbc() + "|" + e.getHybk() + "|" + e.getLbt());
                });
            });
            //妖股晋级率 今日晋级数量/昨日数量
            value = lianBansY.size() != 0 ? new BigDecimal(i.get()).divide(new BigDecimal(lianBansY.size()), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)) : new BigDecimal(0);

            if (gpTj != null && gpTj.getYgJjl() != null) {
                valueStr.append(gpTj.getYgJjl()).append(";");
            }
            valueStr.append(value).append("|").append(i.get()).append("/").append(lianBansY.size());
        }

        gpTjDao.updateById(GpTj.builder().reportTime(reportTime).yg(JsonUtils.obj2String(datas)).ygJjl(valueStr.toString()).build());
    }


    //连板板块统计
    public void lianbanBK(String reportTime) {

//        String reportTime ="2022-06-13";

        LambdaQueryWrapper<GpTj> wrapperQ = new LambdaQueryWrapper<>();
        wrapperQ.eq(GpTj::getReportTime, reportTime);
        GpTj gpTj = gpTjDao.selectOne(wrapperQ);

        if (gpTj == null) {
            gpTjDao.insert(GpTj.builder().reportTime(reportTime).build());
        }


        LambdaQueryWrapper<LianBan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LianBan::getReportTime, reportTime); // 今天
        List<LianBan> lianBans = lianBanDao.selectList(wrapper);

        LambdaQueryWrapper<ShouBan> wrapperS = new LambdaQueryWrapper<>();
        wrapperS.eq(ShouBan::getReportTime, reportTime); // 今天
        List<ShouBan> shouBans = shouBanDao.selectList(wrapperS);

        Map<String, Integer> map = new HashMap();
        Map<String, Integer> mapLB = new HashMap();

        //计算板块
        lianBans.forEach(lianBan -> {
            String hybk = lianBan.getHybk();
            if (map.containsKey(hybk)) {
                map.put(hybk, map.get(hybk) + 1);
            } else {
                map.put(hybk, 1);
            }

            if (mapLB.containsKey(hybk)) {
                mapLB.put(hybk, mapLB.get(hybk) + 1);
            } else {
                mapLB.put(hybk, 1);
            }
        });

        //计算板块
        shouBans.forEach(lianBan -> {
            String hybk = lianBan.getHybk();
            if (map.containsKey(hybk)) {
                map.put(hybk, map.get(hybk) + 1);
            } else {
                map.put(hybk, 1);
            }
        });

        List<Map.Entry<String, Integer>> list = new ArrayList(map.entrySet());

        List<Map.Entry<String, Integer>> listLB = new ArrayList(mapLB.entrySet());

        Collections.sort(list, (o1, o2) -> (o2.getValue() - o1.getValue()));
        Collections.sort(listLB, (o1, o2) -> (o2.getValue() - o1.getValue()));

        String key1 = list.get(0).getKey();
        String key2 = list.get(1).getKey();
        Integer value1 = list.get(0).getValue();
        Integer value2 = list.get(1).getValue();

        String keyLB1 = listLB.get(0).getKey();
        String keyLB2 = listLB.get(1).getKey();
        Integer valueLB1 = listLB.get(0).getValue();
        Integer valueLB2 = listLB.get(1).getValue();

        StringBuffer key = new StringBuffer();
        StringBuffer keyLB = new StringBuffer();
        if (gpTj != null) {
            key.append(gpTj.getZtMaxBk()).append(";");
            keyLB.append(gpTj.getLbMaxBk()).append(";");
        }
        key.append(key1).append("/").append(value1).append("|").append(key2).append("/").append(value2);
        keyLB.append(keyLB1).append("/").append(valueLB1).append("|").append(keyLB2).append("/").append(valueLB2);

        gpTjDao.updateById(GpTj.builder().reportTime(reportTime).ztMaxBk(key.toString()).lbMaxBk(keyLB.toString()).build());

    }
}








